<template>
  <div class="candidate-admin">
    <div class="header">
      <h2 class="title">考生管理</h2>
    </div>

    <!-- 顶部：搜索 + 操作按钮 -->
    <section class="toolbar">
      <div class="ops">
        <el-input v-model="query.account" placeholder="按账号搜索" size="small" style="width: 220px" @keyup.enter="search" />
        <el-select v-model.number="query.status" size="small" placeholder="状态" clearable style="width: 120px">
          <el-option :value="1" label="正常" />
          <el-option :value="0" label="停用" />
        </el-select>
        <el-button size="small" @click="search">查询</el-button>
        <el-button size="small" @click="resetQuery">重置</el-button>
        <el-button size="small" @click="refresh">刷新</el-button>
        <el-button size="small" type="primary" @click="openCreate">新增</el-button>
      </div>
    </section>

    <!-- 底部：列表 + 分页 -->
    <section class="list-card">
      <div class="table-wrap">
        <table>
          <thead>
            <tr>
              <th style="width: 70px;">ID</th>
              <th>头像</th>
              <th>账号</th>
              <th>昵称</th>
              <th>状态</th>
              <th>最后在线</th>
              <th>创建时间</th>
              <th style="width: 220px;">操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="u in list" :key="u.id">
              <td>{{ u.id }}</td>
              <td>
                <img :src="u.avatarUrl || ''" alt="" class="avatar-sm" />
              </td>
              <td>{{ u.account }}</td>
              <td>{{ u.nickname }}</td>
              <td>
                <span :class="u.status === 1 ? 'tag ok' : 'tag err'">
                  {{ u.status === 1 ? '正常' : '停用' }}
                </span>
              </td>
              <td>{{ formatTime(u.lastSeenAt) }}</td>
              <td>{{ formatTime(u.createdAt) }}</td>
              <td class="actions">
                <el-button size="small" type="primary" @click="openDetail(u)">详情</el-button>
                <el-button @click="openEdit(u)">修改</el-button>
                <el-button size="small" type="danger" @click="openDelete(u)">删除</el-button>
              </td>
            </tr>
            <tr v-if="!list.length">
              <td colspan="8" class="empty">暂无数据</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- 分页 -->
      <div class="pagination">
        <div class="left">共 {{ page.total }} 条记录</div>
        <div class="right">
          <button :disabled="page.pageNum <= 1" @click="changePage(page.pageNum - 1)">
          </button>
          <span>第</span>
          <input class="page-input" type="number" :min="1" :max="page.pages || 1" v-model.number="pageInput"
            @change="gotoPage" />
          <span>/ {{ page.pages || 1 }} 页</span>
          <button :disabled="page.pageNum >= (page.pages || 1)" @click="changePage(page.pageNum + 1)">></button>
          <span class="spacer"></span>
          <select v-model.number="query.pageSize" @change="changePageSize">
            <option :value="10">10/页</option>
            <option :value="20">20/页</option>
            <option :value="50">50/页</option>
          </select>
        </div>
      </div>
    </section>

    <!-- 新增/修改 弹窗（统一使用 Element Plus 风格） -->
    <el-dialog v-model="modals.edit.visible" :title="modals.edit.isEdit ? '修改考生' : '新增考生'" width="520px" align-center
      destroy-on-close>
      <el-form :model="form" label-width="100px">
        <el-form-item label="账号">
          <el-input v-model="form.account" placeholder="必填，如：alice" :disabled="modals.edit.isEdit" />
        </el-form-item>
        <el-form-item label="昵称">
          <el-input v-model="form.nickname" placeholder="必填，如：Alice" />
        </el-form-item>
        <el-form-item label="密码">
          <el-input v-model="form.passwordHash" :placeholder="modals.edit.isEdit ? '留空则不修改密码' : '新增必填'" />
        </el-form-item>
        <el-form-item label="头像URL">
          <el-input v-model="form.avatarUrl" placeholder="https://..." />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model.number="form.status" placeholder="请选择状态" style="width: 160px">
            <el-option :value="1" label="正常" />
            <el-option :value="0" label="停用" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeEdit">取消</el-button>
          <el-button type="primary" @click="submit">{{ modals.edit.isEdit ? '保存' : '新增' }}</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 详情 弹窗 -->
    <div v-if="modals.detail.visible" class="modal-backdrop" @click.self="closeDetail">
      <div class="modal">
        <header class="modal-header">
          <h3>考生详情</h3>
          <button class="icon" @click="closeDetail">×</button>
        </header>
        <div class="modal-body">
          <div class="detail-grid">
            <div class="row"><span class="k">ID</span><span class="v">{{ current?.id }}</span></div>
            <div class="row"><span class="k">账号</span><span class="v">{{ current?.account }}</span></div>
            <div class="row"><span class="k">昵称</span><span class="v">{{ current?.nickname }}</span></div>
            <div class="row"><span class="k">状态</span><span class="v">{{ current?.status === 1 ? '正常' : '停用' }}</span>
            </div>
            <div class="row"><span class="k">头像</span><span class="v">{{ current?.avatarUrl || '-' }}</span></div>
            <div class="row"><span class="k">最后在线</span><span class="v">{{ formatTime(current?.lastSeenAt) }}</span>
            </div>
            <div class="row"><span class="k">创建时间</span><span class="v">{{ formatTime(current?.createdAt) }}</span>
            </div>
            <div class="row"><span class="k">更新时间</span><span class="v">{{ formatTime(current?.updatedAt) }}</span>
            </div>
          </div>
        </div>
        <footer class="modal-footer">
          <button class="secondary" @click="closeDetail">关闭</button>
        </footer>
      </div>
    </div>

    <!-- 删除确认 弹窗 -->
    <div v-if="modals.delete.visible" class="modal-backdrop" @click.self="closeDelete">
      <div class="modal small">
        <header class="modal-header">
          <h3>删除确认</h3>
          <button class="icon" @click="closeDelete">×</button>
        </header>
        <div class="modal-body">
          确认删除考生【{{ current?.account }}】吗？该操作不可恢复。
        </div>
        <footer class="modal-footer">
          <button class="danger" @click="doDelete">删除</button>
          <button class="secondary" @click="closeDelete">取消</button>
        </footer>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import {
  pageSysUsers,
  createSysUser,
  updateSysUser,
  deleteSysUser,
  type SysUser,
  type BoPage,
  type SysUserPageParams,
} from '@/api/chat/user'

const query = reactive<SysUserPageParams>({
  account: '',
  status: undefined as unknown as number | undefined,
  pageNum: 1,
  pageSize: 10,
})

const list = ref<SysUser[]>([])
const page = reactive<BoPage<SysUser>>({
  pageNum: 1,
  pageSize: 10,
  total: 0,
  pages: 0,
  list: [],
})

const form = reactive<SysUser>({
  id: undefined,
  account: '',
  passwordHash: '',
  nickname: '',
  avatarUrl: '',
  status: 1,
})

const pageInput = ref(1)
const current = ref<SysUser | null>(null)

const modals = reactive({
  edit: { visible: false, isEdit: false },
  detail: { visible: false },
  delete: { visible: false },
})

function formatTime(t?: string) {
  if (!t) return ''
  try {
    const d = new Date(t)
    const y = d.getFullYear()
    const m = String(d.getMonth() + 1).padStart(2, '0')
    const day = String(d.getDate()).padStart(2, '0')
    const hh = String(d.getHours()).padStart(2, '0')
    const mm = String(d.getMinutes()).padStart(2, '0')
    return `${y}-${m}-${day} ${hh}:${mm}`
  } catch {
    return t || ''
  }
}

async function fetchPage() {
  const params: SysUserPageParams = {
    account: query.account || undefined,
    status: query.status,
    pageNum: query.pageNum,
    pageSize: query.pageSize,
  }
  const res = await pageSysUsers(params)
  const data = res?.data?.data as BoPage<SysUser> | undefined
  if (data) {
    list.value = data.list || []
    Object.assign(page, data)
    pageInput.value = page.pageNum
  } else {
    list.value = []
    Object.assign(page, { pageNum: query.pageNum, pageSize: query.pageSize, total: 0, pages: 0, list: [] })
    pageInput.value = query.pageNum
  }
}

function search() {
  query.pageNum = 1
  fetchPage()
}
function resetQuery() {
  query.account = ''
  query.status = undefined as unknown as number | undefined
  query.pageNum = 1
  query.pageSize = 10
  fetchPage()
}
function changePage(p: number) {
  if (p < 1) p = 1
  if (page.pages && p > page.pages) p = page.pages
  query.pageNum = p
  fetchPage()
}
function gotoPage() {
  changePage(pageInput.value || 1)
}
function changePageSize() {
  query.pageNum = 1
  fetchPage()
}
function refresh() {
  fetchPage()
}

function resetForm() {
  Object.assign(form, {
    id: undefined,
    account: '',
    passwordHash: '',
    nickname: '',
    avatarUrl: '',
    status: 1,
  } as SysUser)
}
function openCreate() {
  resetForm()
  modals.edit.isEdit = false
  modals.edit.visible = true
}
function openEdit(u: SysUser) {
  modals.edit.isEdit = true
  modals.edit.visible = true
  Object.assign(form, {
    id: u.id,
    account: u.account,
    passwordHash: '',
    nickname: u.nickname,
    avatarUrl: u.avatarUrl || '',
    status: u.status ?? 1,
  } as SysUser)
}
function closeEdit() {
  modals.edit.visible = false
}

function openDetail(u: SysUser) {
  current.value = u
  modals.detail.visible = true
}
function closeDetail() {
  modals.detail.visible = false
  current.value = null
}

function openDelete(u: SysUser) {
  current.value = u
  modals.delete.visible = true
}
function closeDelete() {
  modals.delete.visible = false
  current.value = null
}

async function submit() {
  if (!form.account) { ElMessage.warning('请填写账号'); return }
  if (!form.nickname) { ElMessage.warning('请填写昵称'); return }
  if (!modals.edit.isEdit && !form.passwordHash) { ElMessage.warning('新增考生请填写密码Hash'); return }

  const payload: SysUser = { ...form }
  if (modals.edit.isEdit && !form.passwordHash) {
    delete (payload as any).passwordHash
  }

  const res = modals.edit.isEdit && form.id
    ? await updateSysUser(form.id, payload)
    : await createSysUser(payload)

  if ((res?.data?.code ?? res?.data?.status ?? 0) === 0) {
    ElMessage.success('保存成功')
    closeEdit()
    fetchPage()
  } else {
    ElMessage.error('保存失败')
  }
}

async function doDelete() {
  if (!current.value?.id) return
  const res = await deleteSysUser(current.value.id)
  if ((res?.data?.code ?? res?.data?.status ?? 0) === 0) {
    ElMessage.success('删除成功')
    if (list.value.length === 1 && query.pageNum > 1) {
      query.pageNum -= 1
    }
    closeDelete()
    fetchPage()
  } else {
    ElMessage.error('删除失败')
  }
}

onMounted(fetchPage)
watch(() => [query.pageNum, query.pageSize], () => {
  pageInput.value = query.pageNum
})
</script>

<style scoped>
.candidate-admin {
  padding: 6px;
}

.container-card {
  background: #fff;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 20px;
  box-shadow: 0 10px 24px rgba(31, 45, 61, 0.06);
  padding: 20px;
}

.header {
  margin-bottom: 12px;
}

.title {
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
}

.desc {
  margin-top: 6px;
  color: #6b7280;
}

/* 顶部工具栏 */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 12px;
  margin-bottom: 12px;
}

.ops {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* 列表卡片 */
.list-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.table-wrap {
  overflow: auto;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

thead tr {
  background: #f9fafb;
}

th,
td {
  padding: 8px 10px;
  border-bottom: 1px solid #f3f4f6;
  text-align: left;
  white-space: nowrap;
}

td.actions {
  display: flex;
  gap: 8px;
}

.empty {
  text-align: center;
  color: #9ca3af;
}

.avatar-sm {
  width: 28px;
  height: 28px;
  border-radius: 4px;
  object-fit: cover;
  background: #f3f4f6;
}

.tag {
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 12px;
}

.tag.ok {
  background: #dcfce7;
  color: #166534;
}

.tag.err {
  background: #fee2e2;
  color: #991b1b;
}

/* 分页 */
.pagination {
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.pagination .right {
  display: flex;
  align-items: center;
  gap: 6px;
}

.page-input {
  width: 64px;
  padding: 6px 8px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
}

.spacer {
  width: 10px;
}

button.primary {
  background: #16a34a;
}

button.secondary {
  background: #6b7280;
}

button.danger {
  background: #dc2626;
}

button.ghost {
  background: #eef2ff;
  color: #1e3a8a;
}

button.icon {
  background: transparent;
  color: #111827;
  font-size: 18px;
  padding: 4px 8px;
}

/* 弹窗 */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
}

.modal {
  width: min(720px, 92vw);
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e5e7eb;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

.modal.small {
  width: min(420px, 92vw);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid #f1f5f9;
}

.modal-body {
  padding: 14px;
}

.modal-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 12px 14px;
  border-top: 1px solid #f1f5f9;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 12px;
}

.detail-grid .row {
  display: contents;
}

.detail-grid .k {
  color: #6b7280;
  font-size: 12px;
}

.detail-grid .v {
  color: #111827;
  font-size: 13px;
}
</style>
